<template>
  <BasicTable
    ref="tableRef"
    :initial-params="initialParams"
    :form-rules="formRules"
    :query-api="cabinet.queryAll"
    :create-api="cabinet.create"
    :update-api="cabinet.update"
    :delete-api="cabinet.delete"
    :query-fields="queryFields"
    :table-fields="tableFields"
    :form-fields="formFields"
  ></BasicTable>
  <el-drawer v-model="drawerVisible" title="关联设备">
    <div class="flex">
      <el-input
        v-model="deviceListParams.deviceName"
        class="flex-1 mr-2 mb-2"
        placeholder="设备名称"
      ></el-input>
      <el-button type="primary" @click="getDeviceList">查询</el-button>
    </div>
    <el-select
      v-model="selectedDeviceIds"
      class="w-full mb-2"
      multiple
      collapse-tags
    >
      <el-option
        v-for="item in selectedDeviceList"
        :key="item.id"
        :label="item.deviceName"
        :value="item.id"
      />
    </el-select>
    <el-checkbox
      v-model="checkAll"
      :indeterminate="isIndeterminate"
      class="block"
      >全选</el-checkbox
    >
    <el-checkbox-group v-model="selectedDeviceIds" v-loading="loading">
      <el-checkbox
        v-for="item in data"
        :key="item.id"
        class="block"
        :label="item.id"
        @change="(val) => handleCheckboxChange(val, item)"
        >{{ item.deviceName }}（高度：{{ item.height }}）</el-checkbox
      >
    </el-checkbox-group>
    <div class="flex justify-end">
      <el-pagination
        v-model:current-page="deviceListParams.page"
        v-model:page-size="deviceListParams.limit"
        layout="sizes, prev, pager, next"
        :total="deviceListTotal"
        :page-sizes="[10, 20, 50, 100, 200, 500]"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <template #footer>
      <el-button :loading="loading" type="primary" @click="handleConfirmBind"
        >确定</el-button
      >
      <el-button @click="handleCancelBind">取消</el-button>
    </template>
  </el-drawer>
  <el-dialog
    v-model="dialogVisible"
    title="坐标采集"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    @close="handleCancelCollect"
  >
    <template #default>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100">
        <el-form-item label="机房" prop="roomName">
          <el-input v-model="form.roomName" disabled></el-input>
        </el-form-item>
        <el-form-item label="机柜" prop="cabinetName">
          <el-input v-model="form.cabinetName" disabled></el-input>
        </el-form-item>
        <el-form-item label="机器人" prop="robotId">
          <el-select
            v-model="form.robotId"
            class="w-full"
            placeholder="机器人"
            clearable
          >
            <el-option
              v-for="item in robotList"
              :key="item.id"
              :label="item.name"
              :value="item.code"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <el-button
        :loading="loading"
        type="primary"
        @click="handleConfirmCollect"
      >
        确定
      </el-button>
      <el-button @click="handleCancelCollect">取消</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="tsx">
import { ElMessage } from "element-plus";
import { remove, uniq, uniqBy } from "lodash";
import { Fragment, Ref, computed, onMounted, reactive, ref } from "vue";
import { cabinet } from "../../api/cabinet";
import { deviceProfile } from "../../api/deviceProfile";
import { poseGroupApi } from "../../api/poseGroup";
import { robotArchives } from "../../api/robotArchives";
import { roomFile } from "../../api/room";
import { wisdomErrors } from "../../api/wisdomErrors";
import BasicTable from "../../components/BasicTable.jsx";
import parseTime from "../../utils/parseTime";

const initialParams = {
  keyword: "",
  limit: 99999,
};

const formRules = {
  cabinetName: [{ required: true, message: "请输入机柜名称" }],
  // status: [{ required: true, message: "请选择状态" }],
  // rid: [{ required: true, message: "请输入机房id" }],
  // mid: [{ required: true, message: "请输入地图id" }],
  // x: [{ required: true, message: "请输入机柜X坐标" }],
  // y: [{ required: true, message: "请输入机柜y坐标" }],
};

const queryFields = [
  {
    prop: "cabinetName",
    title: "机柜名称",
  },
  {
    prop: "mid",
    title: "地图编号",
  },
  {
    prop: "rid",
    title: "机房编号",
  },
  {
    prop: "status",
    title: "状态",
    slot: (row) => (
      <el-select
        class="w-full"
        v-model={row.value["status"]}
        placeholder="状态"
        clearable
      >
        {Object.entries(statusType).map(([value, label]) => (
          <el-option key={value} label={label} value={value}></el-option>
        ))}
      </el-select>
    ),
  },
];

const tableFields = [
  {
    prop: "id",
    title: "编号",
  },
  {
    prop: "cabinetName",
    title: "机柜名称",
  },
  {
    prop: "theta",
    title: "机柜theta",
  },
  {
    prop: "x",
    title: "机柜X坐标",
  },
  {
    prop: "y",
    title: "机柜y坐标",
  },
  {
    prop: "sort",
    title: "排序",
  },
  {
    prop: "mid",
    title: "地图编号",
  },
  {
    prop: "rid",
    title: "机房编号",
  },
  {
    prop: "threeDModelId",
    title: "模型编号",
  },
  {
    prop: "status",
    title: "状态",
    formatter: (row) => (row === 0 ? "正常" : "不正常"),
  },
  {
    prop: "createTime",
    title: "创建时间",
    formatter: (row) => {
      return parseTime(row);
    },
  },
  {
    prop: "updateTime",
    title: "修改时间",
    formatter: (row) => {
      return parseTime(row);
    },
  },
  {
    title: "操作",
    action: true,
    slot: (row) => (
      <Fragment>
        <el-button link type="success" onClick={() => handleAssign(row)}>
          关联设备
        </el-button>
        <el-button link type="warning" onClick={() => handleCollect(row)}>
          坐标采集
        </el-button>
        <el-button link type="info" onClick={() => handleNavigate(row)}>
          一键导航
        </el-button>
        <el-popover width={300} trigger="click">
          {{
            default: () => (
              <div class="flex">
                <el-select
                  v-model={selectedPoseGroupId.value}
                  size="small"
                  class="flex-1 mr-2"
                  onChange={() => syncPoseGroup(row.id)}
                >
                  {poseGroupData.value.map((item: poseGroupItem) => (
                    <el-option label={item.name} value={item.id}></el-option>
                  ))}
                </el-select>
                {/* <el-button
                  onClick={() => syncPoseGroup(row.id)}
                  type="primary"
                  size="small"
                >
                  确定
                </el-button> */}
              </div>
            ),
            reference: () => (
              <el-button link type="success">
                同步姿态
              </el-button>
            ),
          }}
        </el-popover>
      </Fragment>
    ),
  },
];

const formFields = [
  {
    prop: "cabinetName",
    title: "机柜名称",
  },
  // {
  //   prop: "rid",
  //   title: "机房编号",
  // },
  // {
  //   prop: "mid",
  //   title: "地图编号",
  // },
  {
    prop: "status",
    title: "状态",
    slot: (form) => (
      <el-select class="w-full" v-model={form.value.status}>
        {Object.keys(statusType).map((key) => (
          <el-option label={statusType[key]} value={Number(key)} />
        ))}
      </el-select>
    ),
  },
  {
    prop: "x",
    title: "机柜X坐标",
    slot: (form) => <el-input v-model={form.value.x} type="number"></el-input>,
  },
  {
    prop: "y",
    title: "机柜y坐标",
    slot: (form) => <el-input v-model={form.value.y} type="number"></el-input>,
  },
  {
    prop: "theta",
    title: "机柜θ坐标",
    slot: (form) => (
      <el-input v-model={form.value.theta} type="number"></el-input>
    ),
  },
  {
    prop: "sort",
    title: "排序",
  },
  {
    prop: "threeDModelId",
    title: "模型编号",
  },
];

const statusType = {
  0: "正常",
  1: "不正常",
};

const drawerVisible = ref(false);

const loading = ref(false);
const data = ref([]);
const selectedDeviceIds = ref([]);
let curId: number;

const deviceListParams = reactive({
  page: 1,
  limit: 10,
  deviceName: "",
});
const deviceListTotal = ref(0);

async function handleAssign(row) {
  curId = row.id;
  drawerVisible.value = true;
  getDeviceList();
  const res = await deviceProfile.queryByCid(curId);
  selectedDeviceIds.value = res.data.map((item) => item.id);
  selectedDeviceList.value = res.data || [];
}

async function getDeviceList() {
  loading.value = true;
  try {
    let res = await deviceProfile.queryAll(deviceListParams);
    data.value = res.data.list || [];
    deviceListTotal.value = res.data.total;
  } finally {
    loading.value = false;
  }
}

function handleSizeChange() {
  getDeviceList();
}

function handleCurrentChange() {
  getDeviceList();
}

async function handleConfirmBind() {
  loading.value = true;
  try {
    await deviceProfile.batchBind({
      ids: selectedDeviceIds.value,
      cid: curId,
    });
    ElMessage({ type: "success", message: "关联成功" });
    drawerVisible.value = false;
  } finally {
    loading.value = false;
  }
}

function handleCancelBind() {
  drawerVisible.value = false;
}

const dialogVisible = ref(false);
const form: Ref<{
  robotId?: number;
  cabinetId?: number;
  roomId?: number;
  roomName?: string;
  cabinetName?: string;
}> = ref({});
const rules = {
  robotId: [{ required: true, message: "请选择机器人" }],
};
const robotList = ref([]);
const tableRef = ref(null);

async function handleCollect(row) {
  if (!row.rid) {
    ElMessage({ type: "warning", message: "未绑定机房" });
    return;
  }
  form.value.cabinetId = row.id;
  form.value.roomId = row.rid;
  form.value.cabinetName = row.cabinetName;
  let res = await roomFile.queryById(row.rid);
  form.value.roomName = res.data?.name;
  res = await robotArchives.queryAll({
    limit: 99999,
    RType: "DCInspection",
  });
  robotList.value = res.data.list;
  dialogVisible.value = true;
}

async function handleConfirmCollect() {
  loading.value = true;
  try {
    await cabinet.collectCoordinate(form.value);
    dialogVisible.value = false;
    tableRef.value.getList();
  } finally {
    loading.value = false;
  }
}

function handleCancelCollect() {
  dialogVisible.value = false;
}

async function handleNavigate(row) {
  await wisdomErrors.navigation({
    cabinetId: row.id,
    mid: row.mid,
  });
  ElMessage({ type: "success", message: "发送成功" });
}

const selectedDeviceList = ref([]);

function handleCheckboxChange(value, device) {
  if (value) {
    selectedDeviceList.value.push(device);
  } else {
    remove(selectedDeviceList.value, (item) => item.id === device.id);
  }
}

const isIndeterminate = computed(() => {
  const selectableIds = data.value.map((item) => item.id);
  const selectedIdInSelectable = selectedDeviceIds.value.filter((id) =>
    selectableIds.includes(id)
  );
  if (
    selectedIdInSelectable.length === selectableIds.length ||
    selectedIdInSelectable.length === 0
  ) {
    return false;
  } else {
    return true;
  }
});

const checkAll = computed({
  get() {
    const selectableIds = data.value.map((item) => item.id);
    const selectedIdInSelectable = selectedDeviceIds.value.filter((id) =>
      selectableIds.includes(id)
    );
    if (selectedIdInSelectable.length === selectableIds.length) {
      return true;
    } else {
      return false;
    }
  },
  set(val) {
    const selectableIds = data.value.map((item) => item.id);
    if (val) {
      selectedDeviceIds.value.push(...selectableIds);
      selectedDeviceIds.value = uniq(selectedDeviceIds.value);
      selectedDeviceList.value.push(...data.value);
      selectedDeviceList.value = uniqBy(selectedDeviceList.value, "id");
    } else {
      remove(selectedDeviceIds.value, (id) => selectableIds.includes(id));
      remove(selectedDeviceList.value, (item) =>
        selectableIds.includes(item.id)
      );
    }
  },
});

interface poseGroupItem {
  id: number;
  name: string;
}

const selectedPoseGroupId: Ref<number> = ref();
const poseGroupData: Ref<poseGroupItem[]> = ref([]);
async function getPoseGroupData() {
  const res = await poseGroupApi.getList({ page: 1, limit: 9999999 });
  poseGroupData.value = res.data?.list || [];
}
async function syncPoseGroup(cabinetProfileId) {
  const { message } = await poseGroupApi.syncPoseGroup({
    armParentProfileId: selectedPoseGroupId.value,
    cabinetProfileId,
  });
  ElMessage({ type: "success", message });
  selectedPoseGroupId.value = null;
}

onMounted(() => {
  getPoseGroupData();
});
</script>
